package com.zsd.android.glidelib;

import android.content.Context;
import android.text.TextUtils;
import android.widget.ImageView;

import com.zsd.android.glidelib.cache.ActiveCache;
import com.zsd.android.glidelib.cache.DiskCache;
import com.zsd.android.glidelib.cache.MemoryCache;
import com.zsd.android.glidelib.cache.MemoryCacheCallback;
import com.zsd.android.glidelib.fragment.LifecycleCallback;
import com.zsd.android.glidelib.network.LoadDataManager;
import com.zsd.android.glidelib.network.ResponseListener;
import com.zsd.android.glidelib.resource.Key;
import com.zsd.android.glidelib.resource.Value;
import com.zsd.android.glidelib.resource.ValueCallback;
import com.zsd.android.glidelib.utils.ThreadUtil;

/**
 * 真正去加载资源的
 */
public class RequestTagEngine implements LifecycleCallback, ValueCallback, MemoryCacheCallback, ResponseListener {

    private final int MEMORY_CACHE_MAX_SIZE = 1024 * 1024 * 60;
    //活动缓存
    private ActiveCache activeCache;
    //内存缓存
    private MemoryCache memoryCache;
    //磁盘缓存
    private DiskCache diskCache;
    private String url;
    private Context mContext;
    private String key;
    private ImageView iv;

    public RequestTagEngine() {
        if (activeCache == null) {
            activeCache = new ActiveCache(this);
        }
        if (memoryCache == null) {
            memoryCache = new MemoryCache(MEMORY_CACHE_MAX_SIZE);
            memoryCache.setMemoryCacheCallback(this);
        }
        if (diskCache == null) {
            diskCache = new DiskCache();
        }
    }

    /**
     * RequestManage传递的值
     */
    public void loadValueInitAction (Context mContext, String url) {
        this.mContext = mContext;
        this.url = url;
        key = new Key(url).getKey();
    }

    public void into(ImageView iv) {
        this.iv = iv;
        if (iv == null) {
            throw new IllegalStateException("加载控件不能为空");
        }
        if (!ThreadUtil.isMainThread()) {
            throw new IllegalArgumentException("只能在主线程中操作");
        }
        //todo 加载资源 ---> 缓存 ----> 网络
        Value value = cacheAction();
        if (value != null) {
            value.nonUseAction();
            iv.setImageBitmap(value.getBitmap());
        }
    }

    /**
     * todo 加载资源
     */
    private Value cacheAction() {
        //todo 第一步，判断活动缓存是否有资源，如果有就返回，否则继续往下找
        Value value = activeCache.get(key);
        if (null != value) {
            value.useAction();
            return value;
        }
        //todo 第二步，从内存缓存中去找，如果有就返回，并把缓存加入到活动缓存中，否则继续往下找
        value = memoryCache.get(key);
        if (null != value) {
            //移除内存缓存
            memoryCache.manualRemove(key);
            //把内存缓存的元素加入到活动缓存中
            activeCache.put(key, value);
            value.useAction();
            return value;
        }
        //todo 第三步，从磁盘缓存中去找，如果有就返回，并把缓存加入到活动缓存中，否则网络请求
        value = diskCache.get(key);
        if (null != value) {
            //把磁盘缓存的元素加入到活动缓存中
            activeCache.put(key, value);
            //把磁盘缓存的元素加入到内存缓存中
//            memoryCache.put(key, value);
            value.useAction();
            return value;
        }
        //todo 第四部，真正的去加载外部资源了，去网络上加载/去SD本地上加载
        value = new LoadDataManager().loadResource(mContext, url, this);
        if (null != value) {
            //在SD卡中找到的
            return value;
        }
        return null;
    }

    @Override
    public void glideInitAction() {

    }

    @Override
    public void glideStopAction() {

    }

    @Override
    public void glideRecycleAction() {
        if (activeCache != null) {
            activeCache.closeThread();
        }
    }

    /**
     * 活动缓存间接的调用Value所发出的
     * 回调告诉外界，Value资源不再使用了
     * 监听的方法（Value不再使用）
     * @param key
     * @param value
     */
    @Override
    public void valueNonUseListener(String key, Value value) {
        //把活动缓存操作的Value资源加入到内存缓存中
        if (!TextUtils.isEmpty(key) && value != null) {
            memoryCache.put(key, value);
        }
    }

    /**
     * 内存缓存发出的
     * LRU最少使用的元素被移除了
     * @param key
     * @param oldValue 被移除的Value
     */
    @Override
    public void entryRemovedMemoryCache(String key, Value oldValue) {

    }

    /**
     * 网络加载图片成功
     * @param value
     */
    @Override
    public void success(Value value) {
        if (null != value) {
            saveCache(key, value);
            iv.setImageBitmap(value.getBitmap());
        }
    }

    /**
     * 网络加载图片失败
     * @param e
     */
    @Override
    public void failed(Exception e) {

    }

    /**
     * 保存到缓存中
     * @param key
     * @param value
     */
    private void saveCache(String key, Value value) {
        value.setKey(key);
        if (diskCache != null) {
            diskCache.put(key, value);
        }
    }
}
